package com.mlethe.library.keyboard;

import android.content.Context;
import android.text.Editable;
import android.widget.EditText;

import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 自定义键盘
 *
 * @author Mlethe
 */
public class Keyboard extends android.inputmethodservice.Keyboard implements android.inputmethodservice.KeyboardView.OnKeyboardActionListener {

    protected KeyboardView mKeyboardView;

    public Keyboard(Context context, int xmlLayoutResId) {
        super(context, xmlLayoutResId);
    }

    public Keyboard(Context context, int xmlLayoutResId, int modeId, int width, int height) {
        super(context, xmlLayoutResId, modeId, width, height);
    }

    public Keyboard(Context context, int xmlLayoutResId, int modeId) {
        super(context, xmlLayoutResId, modeId);
    }

    public Keyboard(Context context, int layoutTemplateResId, CharSequence characters, int columns, int horizontalPadding) {
        super(context, layoutTemplateResId, characters, columns, horizontalPadding);
    }

    public void setKeyboardView(KeyboardView keyboardView) {
        this.mKeyboardView = keyboardView;
    }

    /**
     * 当用户按下一个键时调用。 这是在调用onKey之前。
     * 对于重复的键，此键仅调用一次。
     *
     * @param primaryCode 被按下的键的unicode。如果触摸不在有效范围内，值将为零
     */
    @Override
    public final void onPress(int primaryCode) {
        if (isDel(primaryCode)) {
            setPreviewEnabled(false);
        } else {
            setPreviewEnabled(getPreviewEnabled(primaryCode));
        }
    }

    /**
     * 当用户释放键时调用。 这是在调用onKey之后。
     * 对于重复的键，此键仅调用一次。
     *
     * @param primaryCode 被释放的键的unicode
     */
    @Override
    public void onRelease(int primaryCode) {

    }

    /**
     * 发送一个按键到监听器
     *
     * @param primaryCode 这是按下的键
     * @param keyCodes    所有可能的替代键的代码
     */
    @Override
    public final void onKey(int primaryCode, int[] keyCodes) {
        if (mKeyboardView == null) {
            return;
        }
        EditText editText = mKeyboardView.getEditText();
        if (editText == null) {
            return;
        }
        Editable editable = editText.getText();
        int start = editText.getSelectionStart();
        int end = editText.getSelectionEnd();
        if (onKey(primaryCode, editText)) {
            return;
        }
        if (isDel(primaryCode)) {
            // 回退键,删除字符
            if (editable != null && editable.length() > 0 && start > 0 && end > 0) {
                if (end > start) {
                    editable.delete(start, end);
                } else {
                    editable.delete(start - 1, start);
                }
            }
        } else {
            // 输入内容
            editable.replace(start, end, Character.toString((char) primaryCode));
        }
    }

    /**
     * 向侦听器发送一系列字符。
     *
     * @param text 要显示的字符序列。
     */
    @Override
    public void onText(CharSequence text) {

    }

    /**
     * 当用户从右向左快速移动手指时调用
     */
    @Override
    public void swipeLeft() {

    }

    /**
     * 当用户从左向右快速移动手指时调用。
     */
    @Override
    public void swipeRight() {

    }

    /**
     * 当用户从上到下快速移动手指时调用。
     */
    @Override
    public void swipeDown() {

    }

    /**
     * 当用户快速将手指从下向上移动时调用。
     */
    @Override
    public void swipeUp() {

    }

    /**
     * 释放资源
     */
    @CallSuper
    public void destroy() {
        mKeyboardView = null;
    }

    /**
     * 获取 KeyboardView
     *
     * @return
     */
    public KeyboardView getKeyboardView() {
        return mKeyboardView;
    }

    /**
     * 获取 EditText
     *
     * @return
     */
    public EditText getEditText() {
        if (mKeyboardView == null) {
            return null;
        }
        return mKeyboardView.getEditText();
    }

    /**
     * 设置键盘是否可以预览
     *
     * @param previewEnabled
     */
    public final Keyboard setPreviewEnabled(boolean previewEnabled) {
        if (mKeyboardView == null) {
            return this;
        }
        mKeyboardView.setPreviewEnabled(previewEnabled);
        return this;
    }

    /**
     * 切换键盘
     *
     * @param clazz
     */
    public final Keyboard switchKeyboard(Class<? extends Keyboard> clazz) {
        if (mKeyboardView == null) {
            return this;
        }
        mKeyboardView.switchKeyboard(clazz);
        return this;
    }

    /**
     * 判断是不是删除按钮
     *
     * @param primaryCode -5 是删除按键
     * @return true 是  false 不是
     */
    protected boolean isDel(int primaryCode) {
        return primaryCode == KEYCODE_DELETE;
    }

    /**
     * 判断是不是特殊按钮
     *
     * @param primaryCode
     * @return true 是  false 不是
     */
    protected boolean onKey(int primaryCode, @NonNull EditText editText) {
        return false;
    }

    /**
     * 获取是否可以预览
     *
     * @param primaryCode
     * @return
     */
    protected boolean getPreviewEnabled(int primaryCode) {
        return false;
    }

    /**
     * 是否随机键盘
     *
     * @return true 是  false 不是
     */
    public boolean isRandom() {
        return false;
    }

    /**
     * 该按键是否随机
     *
     * @return
     */
    public boolean isRandom(CharSequence charSequence) {
        return isLetterOrNum(charSequence.toString());
    }

    /**
     * 判断是否是字母或数字
     */
    protected boolean isLetterOrNum(String str) {
        if (str.length() > 1) {
            return false;
        }
        Pattern pattern = Pattern.compile("[a-z\\d]");
        Matcher matcher = pattern.matcher(str);
        return matcher.find();
    }
}
